#!/usr/bin/python
# -*- coding: utf-8 -*-
import gtk, gobject, urllib, urllib2, threading, os, sys, time, platform
from thread2 import Thread
import gettext, locale
backend = None
	
if os.environ.get("APPDATA"):					## Pentru ca VLC de Linux are ceva buguri la mansarda
								## si da segfault atunci cand este oprit stream-ul. Fuck VLC
	try:
		path = os.getcwd()
		import vlc
		backend = 'VLC'
		os.chdir(path)
	except:
		sys.path.append(__path__[0])	
		from win32com.client import Dispatch
		backend = 'WMP'
else:
	try:
		path = os.getcwd()
		import vlc
		backend = 'VLC'
		os.chdir(path)
	except:
		import gst, pygst
		backend = 'GST'

if not backend:
	print '[Listen] No backend found. Abort initialization'

def initLang():
	# internationalization suppport
	GETTEXT_DOMAIN = 'Listen'
	LOCALE_PATH = os.path.join(os.path.dirname(os.path.abspath( __file__ )), 'i18n')
	locale.setlocale(locale.LC_ALL, '')
	for module in gtk.glade, gettext:
		module.bindtextdomain(GETTEXT_DOMAIN, LOCALE_PATH)
		module.textdomain(GETTEXT_DOMAIN)	

class Main:
	def __init__(self):
		initLang()
		self.pluginName = 'Listen'
		self.author = 'Ovidiu D. Niţan'
		self.version = '0.16'
		self.descriere = _('This plugin allow playing media files directly in Pymaxe.') + '\nBackend: ' + str(backend)
		self.updatecheck = 'http://redoxwap.freehostia.com/pymaxe_update.php?action=plugin_version&plugin=Listen'
		self.thread = None
		self.volume = 100
		
	def start(self, pymaxe):
		initLang()
		pymaxe.gui.get_object('treeview1').connect("cursor-changed", self.showPlayer, pymaxe)
		global mainGUI
		mainGUI = pymaxe
		mainGUI.Listenplaying = False
		self.gtkb = gtk.Builder()
		self.gtkb.add_from_file(__path__[0] + '/gui.glade')
		self.gtkb.connect_signals({"startListen" : self.startListen, "stopListen" : self.stopListen, "mouseOver" : self.mouseOver, "mouseOut" : self.mouseOut, "suspendSlider" : self.seek, "changeVolume" : self.changeVolume})
		self.gtkb.get_object('eventbox1').add_events(gtk.gdk.POINTER_MOTION_MASK)
		self.gtkb.get_object('hbox2').add_events(gtk.gdk.POINTER_MOTION_MASK)
		pymaxe.ListenGUI = self.gtkb.get_object('vbox1')
		pymaxe.ListenGUI.hide()
		self.gtkb.get_object('label').set_text('')
		pymaxe.statusbar = pymaxe.gui.get_object('statusbar1')
		pymaxe.statusbar.pack_start(pymaxe.ListenGUI, False, True, 0)
		pymaxe.statusbar.reorder_child(pymaxe.ListenGUI, 0)
		global player
		if backend == 'GST':
			player = gst.element_factory_make("playbin2", "player")
			fakesink = gst.element_factory_make("fakesink", "fakesink")
			volume = gst.element_factory_make("volume", "volume")
			player.add(volume)
			player.set_property("volume", int(self.volume/100))
			player.set_property("video-sink", fakesink)
		elif backend == 'VLC':
			player = vlc.MediaPlayer('')
			player.audio_set_volume(int(self.volume))
		elif backend == 'WMP':
			player = Dispatch("WMPlayer.OCX")
			player.settings.volume = int(self.volume)
	
#	def initplayer(self):
#		player = vlc.MediaPlayer('')
			
	def showPlayer(self, obj, pymaxe):
		initLang()
		global lastselection
		try:
			lastselection
		except:
			lastselection = None
		try:
			self.thread.terminate()
		except:
			pass
		treeselection = mainGUI.treeview.get_selection()
		(model, iter) = treeselection.get_selected()
		if not iter:
			return
		url = mainGUI.liststore.get_value(iter, 3);
		if url != lastselection:
			self.gtkb.get_object('adjustment1').set_value(0)
			mainGUI.ListenGUI.hide()
			gobject.idle_add(self.gtkb.get_object('label1').set_text, '00:00')
			gobject.idle_add(self.gtkb.get_object('label2').set_text, '00:00')
			if backend == 'GST':
				player.set_state(gst.STATE_NULL)
			elif backend == 'VLC':
				player.stop()
			elif backend == 'WMP':
				player.controls.stop()
				player.currentPlaylist.clear()
			"""if url.find('trilulilu.ro') != -1:
				mainGUI.ListenGUI.show()
				mainGUI.ListenGUI.set_sensitive(False)
				threading.Thread(target=getTriluliluURL, args=(url, mainGUI)).start()
				self.gtkb.get_object('label').set_text('Loading...')
			if url.find('youtube.com') != -1:
				mainGUI.ListenGUI.show()
				mainGUI.ListenGUI.set_sensitive(False)
				threading.Thread(target=getYouTubeURL, args=(url, mainGUI)).start()
				self.gtkb.get_object('label').set_text('Loading...')"""
			for x in pymaxe.sites:
				mask = pymaxe.sites[x]
				if url.find(mask) != -1:
					mainGUI.ListenGUI.show()
					mainGUI.ListenGUI.set_sensitive(False)
					self.gtkb.get_object('label').set_text(_('Loading...'))
					self.thread = Thread(target=self.runPlayer, args=(x, url, mainGUI, pymaxe))
					self.thread.start()
					break
			self.gtkb.get_object('image1').set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON)
			mainGUI.Listenplaying = False
		lastselection = url

	def runPlayer(self, x, url, mainGUI, pymaxe):
		getURL = pymaxe.plugin[x].fileData(url)
		if getURL == False:
			mainGUI.ListenGUI.hide()
			return
		downurl = getURL['downurl']
		if getURL['format'] == 'image':
			gobject.idle_add(mainGUI.ListenGUI.hide)
			return		
		if backend == 'GST':
			player.set_property("uri", downurl)
			try:
				dur_int = player.query_duration(time_format, None)[0]
			except:
				dur_int = 0
			self.gtkb.get_object('label2').set_text(self.convert_ns(dur_int))
			self.gtkb.get_object('label1').set_text('00:00')
		elif backend == 'VLC':
			player.set_mrl(downurl)
		elif backend == 'WMP':
			tune = player.newMedia(downurl)
			player.currentPlaylist.appendItem(tune)
		pymaxe.ListenGUI.set_sensitive(True)
		self.gtkb.get_object('label').set_text('')

	def startListen(self, obj):
		initLang()
		if mainGUI.Listenplaying == False:
			if backend == 'GST':
				player.set_state(gst.STATE_PLAYING)
			elif backend == 'VLC':
				player.play()
			elif backend == 'WMP':
				player.controls.play()
			treeselection = mainGUI.treeview.get_selection()
			(model, iter) = treeselection.get_selected()
			self.gtkb.get_object('label').set_markup(_('Playing ') + mainGUI.liststore.get_value(iter, 1))
			self.gtkb.get_object('image1').set_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_BUTTON)
			mainGUI.Listenplaying = True
		else:
			if backend == 'GST':
				player.set_state(gst.STATE_PAUSED)
			elif backend == 'VLC':
				player.pause()
			elif backend == 'WMP':
				player.controls.pause()
			treeselection = mainGUI.treeview.get_selection()
			(model, iter) = treeselection.get_selected()
			self.gtkb.get_object('label').set_markup(_('Pause'))
			print _('Pause')
			self.gtkb.get_object('image1').set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON)
			mainGUI.Listenplaying = False
		threading.Thread(target=self.updatePosition).start()

	def stopListen(self, obj):
		if backend == 'GST':
			player.set_state(gst.STATE_NULL)
		elif backend == 'VLC':
			player.stop()
		elif backend == 'WMP':
			player.controls.stop()
		self.gtkb.get_object('label').set_markup('')
		self.gtkb.get_object('image1').set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON)
		gobject.idle_add(self.gtkb.get_object('label1').set_text, '00:00')
		gobject.idle_add(self.gtkb.get_object('adjustment1').set_value, 0)
		mainGUI.Listenplaying = False

	def setUpper(self, obj, value):
                obj.props.upper = value

	def updatePosition(self):
		while True:
			if mainGUI.Listenplaying:
				if backend == 'GST':
					time_format = gst.Format(gst.FORMAT_TIME)
					try:
						dur_int = player.query_duration(time_format, None)[0]
						cur_int = player.query_position(time_format, None)[0]
						gobject.idle_add(self.gtkb.get_object('label1').set_text, self.convert_ns(cur_int))
						gobject.idle_add(self.gtkb.get_object('label2').set_text, self.convert_ns(dur_int))
						gobject.idle_add(self.setUpper, self.gtkb.get_object('adjustment1'), dur_int)
						gobject.idle_add(self.gtkb.get_object('adjustment1').set_value, cur_int)

						if self.convert_ns(cur_int) == self.convert_ns(dur_int):
							self.stopListen(None)
					except:
						pass
				elif backend == 'VLC':
					dur_int = player.get_length() / 1000
					cur_int = player.get_time() / 1000
					gobject.idle_add(self.gtkb.get_object('label1').set_text, time.strftime('%M:%S', time.gmtime(cur_int)))
					gobject.idle_add(self.gtkb.get_object('label2').set_text, time.strftime('%M:%S', time.gmtime(dur_int)))
					gobject.idle_add(self.setUpper, self.gtkb.get_object('adjustment1'), dur_int)
					gobject.idle_add(self.gtkb.get_object('adjustment1').set_value, cur_int)
				elif backend == 'WMP':
					try:
						dur_int = player.currentMedia.duration
						cur_int = player.controls.currentPosition
						gobject.idle_add(self.setUpper, self.gtkb.get_object('adjustment1'), dur_int)
						gobject.idle_add(self.gtkb.get_object('adjustment1').set_value, cur_int)
						cur = time.strftime('%M:%S', time.gmtime(cur_int))
						dur = time.strftime('%M:%S', time.gmtime(dur_int))
						gobject.idle_add(self.gtkb.get_object('label1').set_text, cur)
						gobject.idle_add(self.gtkb.get_object('label2').set_text, dur)
						if cur == int(dur_int) - 1:
							self.stopListen(None)
					except Exception, e:
						print e
					
				time.sleep(0.2)
			else:
				break

	def mouseOver(self, obj, event):
		self.gtkb.get_object('label').hide()
		self.gtkb.get_object('hbox2').show()

	def mouseOut(self, obj, event):
		source_id = gobject.timeout_add(1500, self.reShow, True)

	def reShow(self, do):
		if do:
			self.gtkb.get_object('label').show()
			self.gtkb.get_object('hbox2').hide()
		return False
		
	def changeVolume(self, obj, event):
		volume = obj.get_value()
		if backend == 'GST':
			self.volume = volume / 100
			player.set_property("volume", self.volume)
		elif backend == 'VLC':
			player.audio_set_volume(int(volume))
		elif backend == 'WMP':
			player.settings.volume = int(volume)

	def seek(self, obj, event, value):
		global source_id
		try:
			gobject.source_remove(source_id)
		except:
			pass
		source_id = gobject.timeout_add(1500, self.reShow, True)
		if backend == 'GST':
			time_format = gst.Format(gst.FORMAT_TIME)
			player.seek_simple(time_format, gst.SEEK_FLAG_FLUSH, value)
		elif backend == 'VLC':
			player.set_time(int(value)*1000)
		elif backend == 'WMP':
			player.controls.currentPosition = value

	def convert_ns(self, time_int):
			time_int = time_int / 1000000000
			time_str = ""
			if time_int >= 3600:
				_hours = time_int / 3600
				time_int = time_int - (_hours * 3600)
				time_str = str(_hours) + ":"
			if time_int >= 600:
				_mins = time_int / 60
				time_int = time_int - (_mins * 60)
				time_str = time_str + str(_mins) + ":"
			elif time_int >= 60:
				_mins = time_int / 60
				time_int = time_int - (_mins * 60)
				time_str = time_str + "0" + str(_mins) + ":"
			else:
				time_str = time_str + "00:"
			if time_int > 9:
				time_str = time_str + str(time_int)
			else:
				time_str = time_str + "0" + str(time_int)
			
			return time_str

	def showDialog(self, type, title, message):
			gtk.gdk.threads_enter()
			dialog = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_CLOSE, message_format=message);
			dialog.set_title(title);
			dialog.run();
			dialog.destroy();
			gtk.gdk.threads_leave()

	def quit(self):
		exit()
	
	def uninstall(self, pymaxe):
		pymaxe.ListenGUI.hide()
		global player
		try:
			if backend == 'GST':
				player.set_state(gst.STATE_NULL)
			elif backend == 'VLC':
				player.stop()
			elif backend == 'WMP':
				player.controls.stop()
			del player
			del gtkb
		except:
			pass
